package vfs.obj.association;

import vfs.obj.entity.VFSNode;
import vfs.filter.VFSFilter;
import vfs.obj.entity.VFSPathAncestor;
import vfs.obj.entity.VFSPathDescendant;
import java.util.Iterator;

/**
 * VFSPath is an association manipulator capable of 
 * manipulating the path relationships between Nodes and
 * their ancestors or descendants.
 * 
 * @author Matthew Eavenson <durandal@uga.edu>
 */
public interface VFSPath{
    
    /**
     * Returns an iterator over all ancestors of a specified node,
     * and filtered by a specified filter.
     * 
     * @param descendant the descendant
     * @param filter a filter over the ancestors with the specified type
     * @return an iterator over any matching ancestors
     */
    Iterator<VFSPathAncestor> getAncestors(VFSNode descendant, VFSFilter filter);
    
    /**
     * Returns an iterator over all descendants of a specified node,
     * and filtered by a specified filter.
     * 
     * @param ancestor the ancestor
     * @param filter a filter over the descendants with the specified type
     * @return an iterator over any matching descendants
     */
    Iterator<VFSPathDescendant> getDescendants(VFSNode ancestor, VFSFilter filter);
    
    /**
     * Returns the ancestor of a specified node at a specified level of the hierarchy.
     * 
     * @param descendant the descendant node
     * @param length the number of levels between the requested ancestor and the specified descendant
     * @return the ancestor at the specified level if it exists, null otherwise
     */
    VFSNode getAncestor(VFSNode descendant, int length);
    
    /**
     * Returns an iterator over all descendant nodes of a specified node at a
     * specified level of the hierarchy.
     * 
     * @param ancestor the ancestor node
     * @param length the number of levels between the specified ancestor and the requested descendants
     * @return an iterator over any matching descendant nodes
     */
    Iterator<VFSNode> getDescendants(VFSNode ancestor, int length);
    
    /**
     * Adds a path relationship between a specified ancestor and a specified descendant
     * with a specified length.
     * 
     * @param ancestor the ancestor node
     * @param descendant the descendant node
     * @param length the number of levels between the specified ancestor and the specified descendant
     */
    void addPath(VFSNode ancestor, VFSNode descendant, int length);
    
    /**
     * Removes a path relationship between a specified ancestor and a specified descendant.
     * 
     * @param ancestor the ancestor node
     * @param descendant the descendant node
     */
    void removePath(VFSNode ancestor, VFSNode descendant);
    
    /**
     * Removes all path relationships from a specified node.  Usually only used when a node is
     * about to be removed from the system.
     * 
     * @param node the node for which to remove all path information
     */
    void removeAll(VFSNode node);
    
    /**
     * Removes all ancestor relationships from a specified node above a given level.  Usually 
     * only used when a node is being moved.
     * 
     * @param node the node for which to remove all ancestor information
     * @param length the level above which ancestors will be removed
     */
    void removeAncestors(VFSNode node, int length);
    
    /**
     * Alters the length between an ancestor and a descendant.  Will have no 
     * effect if there is not a preexisting ancestor/descendant relationship.
     * 
     * @param ancestor the ancestor for which length information will be altered with respect to the specified descendant
     * @param descendant the descendant for which length information will be altered with respect to the specified ancestor
     * @param length the new length between the ancestor and descendant
     */
    void alterPath(VFSNode ancestor, VFSNode descendant, int length);
    
}
